/**
 * Copyright (c) 2003-2017 Ben Lau
 * All rights reserved.
 */
package proxy;

import java.lang.reflect.Proxy;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;
import net.sf.cglib.proxy.Enhancer;
import proxy.cglib.CglibDbQueryInterceptor;
import proxy.javaassist.JavassistDynDbQueryHandler;
import proxy.jdk.JdkDBQueryHandler;
import proxy.statics.DBQuery;
import proxy.statics.IDBQuery;

/**
 * @author liubin
 *
 */
public class ProformanceTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

	}

	public static IDBQuery createJdkProxy() {
		IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
				new Class[] { IDBQuery.class }, new JdkDBQueryHandler());
		return jdkProxy;
	}

	public static IDBQuery createCglibProxy() {
		Enhancer enhancer = new Enhancer();
		enhancer.setCallback(new CglibDbQueryInterceptor());
		enhancer.setInterfaces(new Class[] { IDBQuery.class });
		IDBQuery cglibProxy = (IDBQuery) enhancer.create();
		return cglibProxy;
	}

	/**
	 * 使用代理工厂创建Javassist代理
	 * 
	 * @return
	 * @throws Exception
	 */
	public static IDBQuery createJavassistDynDbQueryHandler() throws Exception {
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setInterfaces(new Class[] { IDBQuery.class });
		Class proxyClass = proxyFactory.createClass();
		IDBQuery javassistProxy = (IDBQuery) proxyClass.newInstance();

		((ProxyObject) javassistProxy).setHandler(new JavassistDynDbQueryHandler());

		return javassistProxy;
	}

	/**
	 * 使用动态java代码来创建代理
	 * 
	 * @return
	 * @throws Exception
	 */
	public static IDBQuery createJavassistBytecodeDynamicProxy() throws Exception {
		ClassPool mPool = new ClassPool();

		// 定义类名
		CtClass mCtClass = mPool.makeClass(IDBQuery.class.getName() + "JavassistBytecodeProxy");
		// 需要实现的接口
		mCtClass.addInterface(mPool.get(IDBQuery.class.getName()));
		// 添加构造函数，使用动态Java实例
		mCtClass.addConstructor(CtNewConstructor.defaultConstructor(mCtClass));

		// 添加类的字段信息
		mCtClass.addField(CtField.make("public" + IDBQuery.class.getName() + "real;", mCtClass));

		String dbqueryname = DBQuery.class.getName();

		// 添加方法，这里使用动态Java代码指定内部逻辑
		mCtClass.addMethod(CtNewMethod.make(
				"public String request() {if(real==null) real=new " + dbqueryname + "();return real.request();}",
				mCtClass));

		// 基于以上信息生成动态代理类
		Class pc = mCtClass.toClass();

		// 生成动态代理类的实例
		IDBQuery bytecodeProxy = (IDBQuery) pc.newInstance();

		return bytecodeProxy;
	}
}
